#ifndef __CoordinationTaskGoal_h__
#define __CoordinationTaskGoal_h__

#pragma once


#include "CoordinationTask.h"
#include "CoordinationTaskSync.h"


class CoordinationTaskGoal
	: public CoordinationTask
{
public:
	CoordinationTaskGoal(const CoordinationSetup* setup, const CoordinationTaskMonitor* taskMonitor);

	bool LoadFromXML(int roleID, const XmlNodeRef& rootNode);

	virtual const char* GetName() const;
	virtual const char* GetDescription() const;
	virtual ECoordinationState GetActorState(const CoordinationID& coordinationID, const CoordinationActor& actor) const;
	virtual ECoordinationState GetState(const CoordinationID& coordinationID) const;
	virtual bool CanStart(const CoordinationID& coordinationID, const CoordinationActors& assignees) const;
	virtual void Start(const CoordinationID& coordinationID, const CoordinationActors& assignees);
	virtual void Stop(const CoordinationID& coordinationID);
	virtual void Stop(const CoordinationID& coordinationID, const CoordinationActor& actor);
	virtual void Update(float frameTime);
	virtual void Serialize(TSerialize ser);

private:

	typedef struct ActorState
	{
		float timeout;
		ECoordinationState state;
		int pipeID;

		void Serialize(TSerialize ser)
		{
			ser.Value("timeout", timeout);
			ser.EnumValue("state", state, CoordinationNotRunning, CoordinationFinished);
		}
	};

	typedef std::map<CoordinationActor, ActorState> ActorStates;

	typedef struct RunningGoal : IGoalPipeListener
	{
		RunningGoal()
			: state(CoordinationRunning)
			, activeCount(0)
		{
		}
		~RunningGoal();
		void ClearListeners();

		ActorStates actors;
		int activeCount;
		ECoordinationState state;

		// IGoalPipeListener
		virtual void OnGoalPipeEvent( IPipeUser* pPipeUser, EGoalPipeEvent event, int goalPipeId );

		void Serialize(TSerialize ser)
		{
			ser.Value("actors", actors);
			ser.Value("activeCount", activeCount);
			ser.EnumValue("state", state, CoordinationNotRunning, CoordinationFinished);
		}
	};

	typedef std::map<CoordinationID, RunningGoal> RunningGoals;
	RunningGoals m_running;

	string m_goalpipeName;
	int m_typeId;
	float m_timeout;

	CoordinationTaskSync m_sync;

	const CoordinationSetup* m_setup;
	const CoordinationTaskMonitor* m_taskMonitor;
};


#endif //__CoordinationTaskGoal_h__